<?php

require_once dirname(__FILE__).'/../lib/locationGeneratorConfiguration.class.php';
require_once dirname(__FILE__).'/../lib/locationGeneratorHelper.class.php';

/**
 * location actions.
 *
 * @package    tfe
 * @subpackage location
 * @author     Derboven Jerome
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class locationActions extends autoLocationActions {

    // surcharge pour inscription rapide
    public function executeNew(sfWebRequest $request) {
        $id = $request->getParameter('id');
        if($id) {
            $ins = new Location();
            $ins->setIdContact($request->getParameter('id'));
            $this->form = new LocationForm($ins);
        }else {
            $this->form = $this->configuration->getForm();
        }
        $this->location = $this->form->getObject();
    }

    // processForm pour définir des règles lors
    protected function processForm(sfWebRequest $request, sfForm $form) {
        // recuperer le formulaire ['location']
        $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));


        if ($form->isValid()) {
            // le form ne verifie pas de base (cf modele) si la date a ete specifiee
            // donc le test est a faire ici
            $sallesOccupees = false;
            if (!is_null($form->getValue('date'))) {
                // les salles
                if ($form->getObject()->isNew() && !is_null($form->getValue('salles_list'))) {
                    // recuperer l'etat des salles
                    $etatSalles = $this->getDisponibiliteSalles($form);

                    // voir si les salles sont dispos
                    $msgSallesReservees = "";
                    foreach($etatSalles as $idSalle => $disponibilite) {
                        if (!$disponibilite) {
                            $sallesOccupees = true;
                            break;
                        }
                    }
                }

                // si aucune des salles choisies n'est reservees alors on valide, et on crée les "occupations de salle"
                if (!$sallesOccupees) {
                    
                    $notice = $form->getObject()->isNew() ? 'The item was created successfully.' : 'The item was updated successfully.';
                    $location = $form->save();

                    foreach($location->getSalles() as $salle){

                        // supprimer les précédédents occupation (si update)
                        if(!$form->getObject()->isNew()){
                            $del = Doctrine_Query::create()
                                ->delete()
                                ->from('OccupationSalle')
                                ->where('id_location = ?', $location->getId());
                        }

                        //
                        $occupation = new OccupationSalle();

                        if($location->getContact() != ''){
                            $occupation->setLibelle('Location par '. $location->getContact());
                        }else{
                            $occupation->setLibelle('Location par le groupe '. $location->getGroupe());
                        }

                        $occupation->setCommentaire('');
                        $occupation->setLieu($salle);
                        $occupation->setDate($form->getValue('date'));
                        $occupation->setLocation($location);
                        $occupation->setHeureDeDebut($location->getHeureDeDebut());
                        $occupation->setHeureDeFin($location->getHeureDeFin());

                        $occupation->save();

                    }

                    // logique initiale
                    $this->dispatcher->notify(new sfEvent($this, 'admin.save_object', array('object' => $location)));

                    if ($request->hasParameter('_save_and_add')) {
                        $this->getUser()->setFlash('notice', $notice.' You can add another one below.');
                        $this->redirect('@location_new');
                    } else {
                        $this->getUser()->setFlash('notice', $notice);
                        $this->redirect(array('sf_route' => 'location_edit', 'sf_subject' => $location));
                    }
                } else {
                    $this->getUser()->setFlash('error', 'La ou les salle(s) que vous avez sélectionnée(s) sont déjà réservées', false);
                }
            } else {
                $this->getUser()->setFlash('error', 'Vous devez spécifier une date pour la location', false);
            }
        } else {
            $this->getUser()->setFlash('error', 'The item has not been saved due to some errors.', false);
        }
    }

    // renvoie un array contenant la disponibilite de toutes les salles
    private function getDisponibiliteSalles($form) {
        $etatSalles = array();

        foreach ($form->getValue('salles_list') as $idSalle) {

            // test sur les dates des evenements
            $evenements = Doctrine::getTable('Evenement')->findBy('lieu', $idSalle);
            $salleDispoEvenement = $this->getEtatSalle($form, null, $evenements);

            // test sur les locations
            $listeSalles = Doctrine::getTable('ListeSalles')->findBy('id_salle', $idSalle);
            // au cas ou la salle ne serait reservee pour aucune location, il n'y aurait que les events a tester
            if (0 != count($listeSalles)) {
                foreach ($listeSalles as $idLocation) {
                    $locations  = Doctrine::getTable('Location')->findBy('id', $idLocation->getIdLocation());
                    $salleDispoLocation = $this->getEtatSalle($form, $locations);
                    if (1 == $salleDispoLocation && 1 == $salleDispoEvenement) {
                        $etatSalles[$idSalle] = true;
                    } else {
                        $etatSalles[$idSalle] = false;
                    }
                }
            } else {
                if (1 == $salleDispoEvenement) {
                    $etatSalles[$idSalle] = true;
                } else {
                    $etatSalles[$idSalle] = false;
                }
            }

        }

        return $etatSalles;
    }


    // traite a la fois les locations et les evenements
    // donne l'etat (occupe ou non) d'une salle definie
    private function getEtatSalle($form, $locations = null, $evenements = null) {
        $dispo = 1;

        // test si evenement ou location
        if (!is_null($locations) XOR !is_null($evenements)) {
            if (!is_null($locations)) {
                $services = $locations;
            } else if (!is_null($evenements)) {
                $services = $evenements;
            }

            foreach($services as $service) {
                if ($form->getValue('date') == $service->getDate()) {
                    if (!is_null($form->getValue('heure_de_debut'))) {
                        if (!is_null($form->getValue('heure_de_fin'))) {
                            $heureDebut = strtotime(date($form->getValue('heure_de_debut')));
                            $heureFin   = strtotime(date($form->getValue('heure_de_fin')));
                            $serviceHeureDebut = strtotime(date($service->getHeureDeDebut()));
                            $serviceHeureFin   = strtotime(date($service->getHeureDeFin()));

                            if ($heureDebut < $serviceHeureDebut && $heureFin <= $serviceHeureDebut) {
                                $dispo = 1;
                            } else if ($heureDebut >= $serviceHeureFin && $heureFin > $serviceHeureFin) {
                                $dispo = 1;
                            } else {
                                $dispo = 0;
                            }

                        } else {
                            // alors on considere que ca prend le restant de la journee
                            $heureDebut = strtotime(date($form->getValue('heure_de_debut')));
                            $serviceHeureDebut = strtotime(date($service->getHeureDeDebut()));

                            if ($heureDebut >= $serviceHeureDebut) {
                                $dispo = 0;
                            } else {
                                $dispo = 1;
                            }
                        }
                    } else {
                        $dispo = 0;
                    }
                }
            }
        } else {
            throw new Exception('Une location ou un événement au moins, pas les deux');
        }

        return $dispo;
    }
    

    // utile pour que les actions batch respectent le softDelete
    protected function executeBatchDelete(sfWebRequest $request) {
        $ids = $request->getParameter('ids');

        $records = Doctrine_Query::create()
                ->select()
                ->from('Location')
                ->whereIn('id', $ids)
                ->execute();

        $count = 0;
        foreach($records as $record) {
            $count += $record->delete();
        }

        if ($count >= count($ids)) {
            $this->getUser()->setFlash('notice', 'The selected items have been deleted successfully.');
        }
        else {
            $this->getUser()->setFlash('error', 'A problem occurs when deleting the selected items.');
        }

        $this->redirect('@location');
    }

}
